{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "GraphCuts is the name for a collection of energy minimization algorithms (https://en.wikipedia.org/wiki/Graph_cuts_in_computer_vision). We employ it here for image segmentation.\n",
    "\n",
    "This scripts performs a marker based image segmentation by constructing a graph from the images voxels and then looking for the globally optimal cut to seperate the marker areas.\n",
    "\n",
    "Various versions are provided (http://pythonhosted.org/MedPy/graphcut.html), but we will concentrate here on only two."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Gradient based"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<table>\n",
    "<tr>\n",
    "<td><img alt=\"\" src=\"images/b0.png\" width=\"200\" /></td>\n",
    "<td><img alt=\"\" src=\"images/b0wmarker.png\" width=\"200\" /></td>\n",
    "<td><img alt=\"\" src=\"images/b0gradient.png\" width=\"200\" /></td>\n",
    "</tr>\n",
    "<tr>\n",
    "<td>Original image</td>\n",
    "<td>Foreground (red) and background (green) marker on original image</td>\n",
    "<td>Gradient image</td>\n",
    "</tr>\n",
    "</table>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's assume we want to segment the ventricle from a brain scan (left image). We first create some (manual or automatic) markers (middle image). We furthermore require a gradient magnitude image of the brain scan, which we can obtain with"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "medpy_gradient.py resources/b0.nii.gz output/gradient.nii.gz"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To execute the graphcut, we call"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "medpy_graphcut_voxel.py 10 output/gradient.nii.gz resources/b0markers.nii.gz output/graphcut_voxel_gradient.nii.gz --boundary diff_pow"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Which results in\n",
    "<img alt=\"voxel GC result gradient based\" src=\"images/graphcut_voxel_gradient.png\" width=\"300\" /></td>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Which is acceptable, considering the ad-hoc usage we just performed. The first parameter passed to the script defines the *sigma*, i.e., the smoothness of the cut. Setting it to high will result in very smooth cuts, lower values allow the graphcut more freedom at the risk of leakages."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Grayvalue based"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Another usage of the script does not require the magnitude gradient, but rather the original image. It can be used by calling"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "medpy_graphcut_voxel.py 1 resources/b0.nii.gz resources/b0markers.nii.gz output/graphcut_voxel_grayvalues.nii.gz --boundary=max_div"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Which results in\n",
    "<img alt=\"voxel GC result gradient based\" src=\"images/graphcut_voxel_grayvalues.png\" width=\"300\" /></td>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This result is smoother and dooes better represent the real outline of the ventricles. But it failed to connect one of the foreground markers with the remaining foreground object."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Summary"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Graphcuts are a frickle thing. They depend on the quality of the markers and the employed parameters. The examples shown here provide quite acceptable results that could be easily improved with further parameter tuning.\n",
    "\n",
    "Furthermore, this script only uses the boundary term of graphcut, ignoring the regional term. **MedPy** does of course support both terms, see the package description for more details: http://pythonhosted.org/MedPy/graphcut.html\n",
    "\n",
    "For very large (e.g. 4D) images, the voxel based graphcut might be too memory consuming for a standard computer. You might want to consider using the label/region based grapcut shipped with **MedPy** instead. The label/region version is additionally faster and often produces superior results."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Bash",
   "language": "bash",
   "name": "bash"
  },
  "language_info": {
   "codemirror_mode": "shell",
   "file_extension": ".sh",
   "mimetype": "text/x-sh",
   "name": "bash"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
